<?php
// 应用公共文件
use PhpAmqpLib\Connection\AMQPSocketConnection;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;
use think\facade\Log;
use think\response\Json;

function jsonReturn($code, $message, $data = [], $statusCode = 200, $header = []): Json
{
    $result = [
        'code' => $code,
        'message' => $message,
        'result' => $data,
    ];
    return json($result, $statusCode, $header);
}

function commonRecursion($list, $pid = 0, $level = 0, $col = 'pid', $sub = 'child', $isFilter = false): array
{
    $result = [];
    foreach ($list as $key => $val) {
        if ($val[$col] == $pid) {
            $val[$sub] = commonRecursion($list, $val['id'], $level++, $col, $sub);
            if ($isFilter && empty($val[$sub])) {
                unset($val[$sub]);
            }
            $result[] = $val;
            unset($list[$key]);
        }
    }

    return $result;
}

function encrypt($data): string|bool
{
    try {
        return base64_encode(openssl_encrypt($data, env('openssl_cipher_algo'), env('openssl_key'), OPENSSL_RAW_DATA, env('openssl_iv')));
    } catch (Exception $e) {
        return false;
    }
}

function decrypt(string $data): bool|string
{
    try {
        return openssl_decrypt(base64_decode($data), env('openssl_cipher_algo'), env('openssl_key'), OPENSSL_RAW_DATA, env('openssl_iv'));
    } catch (Exception $e) {
        return false;
    }
}

/**
 * 名称：隐藏字符串(字母|数字)中间字符
 * @param string $string |null $string
 * @param array $option 需要保留及替换为星号的长度数组
 * @return string|null
 */
function strDesensitize(string $string, array $option = [3, 4]): ?string
{
    try {
        [$front, $end,] = $option;
        $middle = mb_strlen($string) - $front - $end;
        if (!$string || !is_array($option) || 2 !== count($option) || !$middle) {
            return $string;
        }

        return preg_replace("/^(\w{{$front}})(\w{{$middle}})(\w{{$end}})$/", '$1****$3', $string);
    } catch (Exception $e) {
        return null;
    }
}

function getUserInfo($authorization = null)
{
    try {
        $authorization = $authorization ?? request()->header('authorization');
        $userInfo = cache("userInfo:{$authorization}");
        if (!$userInfo) {
            throw new Exception('用户信息不存在！');
        }

        $userInfo = is_array($userInfo) ? $userInfo : json_decode($userInfo, true);
        if (!$userInfo) {
            throw new Exception('用户信息错误！');
        }

        return $userInfo;
    } catch (Exception $e) {
        return null;
    }
}

function generateRandomString($length = 4): string
{
    $string = str_shuffle('ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789');
    $result = '';
    for ($i = 0; $i < $length; $i++) {
        $result .= $string[$i];
    }

    return $result;
}


function rabbitmqConnect()
{
    try {
        $host = env('mq_host');
        $port = env('mq_port');
        $userName = env('mq_username');
        $password = env('mq_password');
        $queueName = env('mq_queue_name');
        $exchangeName = env('mq_exchange_name');
        $routeKey = env('mq_route_key');
        $vhost = env('mq_vhost');

        $connection = new AMQPSocketConnection($host, $port, $userName, $password, $vhost, false, 'AMQPLAIN', null, 'en_US', 3.0, true, null, 60);
        $channel = $connection->channel();

        $channel->exchange_declare($exchangeName, 'direct', false, true, false);

        $channel->queue_declare($queueName, false, true, false, false, false, new AMQPTable([
            'x-message-ttl' => 86400000, //消息存活时间，单位毫秒
        ]));
        $channel->queue_bind($queueName, $exchangeName, $routeKey);

        return $channel;
    } catch (Exception $e) {
        Log::write('[error]rabbitmq连接错误：' . $e->getMessage(), 'error');
        return false;
    }
}

function rabbitmqPush($data)
{
    try {
        $channel = rabbitmqConnect();
        if (!$channel) {
            return false;
        }

        $exchangeName = env('mq_exchange_name');
        $routeKey = env('mq_route_key');

        $message = new AMQPMessage($data);
        $channel->basic_publish($message, $exchangeName, $routeKey);

        //$channel->basic_consume($queueName, '', false, false, false, false, [$this, 'consume']);
        return $channel;
    } catch (Exception $e) {
        Log::write('[error]rabbitmq数据推送错误：' . $e->getMessage(), 'error');
        return false;
    }
}